-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
main: Ignore SIGPIPE when printing version #3203
Conversation
In order to do a runtime feature check, `ostree --version` can be piped to `grep` or similar. However, if the read end of the pipe doesn't read all of the output, `ostree` will receive `SIGPIPE` when trying to write output. Ignore it so that `ostree` still exits successfully in that case.
I couldn't actually test this on my local machine since I could never trigger the |
Hmmm...I am wondering if there is precedent for this in other projects. GLib is not alone in changing |
And yeah per my comment here...fun fact is that glib changes it in the class constructor for GSocket. Not that we're going to make a socket in the printing code for |
Because I didn't actually understand this behavior, I decided to look it up. Per pipe(7), if you don't ignore |
That rust issue has a link to an interesting interpretation of |
@@ -510,6 +511,11 @@ ostree_option_context_parse (GOptionContext *context, const GOptionEntry *main_e | |||
|
|||
if (opt_version) | |||
{ | |||
/* Ignore SIGPIPE so that piping the output to grep or similar | |||
* doesn't cause the process to fail. */ | |||
if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually wait though, shouldn't we be setting it to SIG_DFL
here so we get killed by SIGPIPE, which the shell is expecting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's exactly what's happening now. The default disposition for SIGPIPE
is to kill the process. The process gets killed and the shell sets the exit status to 128 + signum = 141. The pipefail
feature says that any process with a non-0 exit status is considered failed. I think it would be better if bash saw the SIGPIPE
triggered exit and treated it as a successful exit, but that's not what it does. See https://lists.nongnu.org/archive/html/bug-bash/2017-03/msg00179.html for one of the util-linux maintainers unsuccessfully trying to convince the bash maintainers to do that.
By ignoring the signal, the process won't be killed. Instead, all the writes will fail with EPIPE
, which g_print
will ignore. That's not so nice since it will keep trying to write data even though there's no reader. However, since the opt_version
output is small and controlled, it's no big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, thanks. So basically there's no way to get strict error handling right now for pipes that works reliably.
Yeah. I think the answer here is to not use shell script...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I think the answer here is to not use shell script...
Exactly. For me it's kinda sad because my entry point to software was elaborate shell scripts to do various things. But after being bitten by one too many of these gotchas I've mostly stopped writing them unless they're very simple.
Unlike `grep`, `grep -q` will exit 0 as soon as a match is found. This will cause whatever is writing into `grep` to hit `SIGPIPE`. And if it's not equipped to handle that signal, it'll be terminated and the overall if-condition will always fail due to `-o pipefail`. See also ostreedev/ostree#3203.
In order to do a runtime feature check,
ostree --version
can be piped togrep
or similar. However, if the read end of the pipe doesn't read all of the output,ostree
will receiveSIGPIPE
when trying to write output. Ignore it so thatostree
still exits successfully in that case.